package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.commmon.R;
import org.example.dto.MedicineDto;
import org.example.mapper.MedicineMapper;
import org.example.pojo.Category;
import org.example.pojo.Medicine;
import org.example.pojo.MedicineStandard;
import org.example.service.CategoryService;
import org.example.service.MedicineStandardService;
import org.example.service.MedicineService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;


@Service
public class MedicineServiceImpl<D extends BaseMapper<MedicineStandard>, D1> extends ServiceImpl<MedicineMapper, Medicine> implements MedicineService {


    @Autowired
    private MedicineStandardService medicineStandardService;


    @Autowired
    private CategoryService categoryService;

    @Autowired
    private MedicineService medicineService;


    /**
     * 多张表控制
     * 加上Transactional注解
     * @param medicineDto
     */

    @Transactional
    @Override
    public void saveWithStandard(MedicineDto medicineDto) {
        //对药品表来说 药品的名称 价格 类别 图片 描述被前端页面提交
        this.save(medicineDto);

        //当药品表保存完成之后 会在数据库中生成药品的唯一id
        Long medicineId = medicineDto.getId();

        //获取到使用标准列表
        List<MedicineStandard> medicineStandards = medicineDto.getStandards();
        for (int i = 0; i < medicineStandards.size(); i++) {
            MedicineStandard medicineStandard = medicineStandards.get(i);

            medicineStandard.setMedicineId(medicineId);
//            System.out.println(medicineStandard);
            medicineStandardService.save(medicineStandard);
        }
//        System.out.println(medicineStandards);
        //对于使用标准表来说
        /**
         * saveBatch
         * mp提供的对集合的插入
         */
//        medicineStandardService.saveBatch(medicineStandards);

    }

    @Override
    public MedicineDto getByIdWithStandard(Long id) {
        Medicine medicine=this.getById(id);
        MedicineDto medicineDto = new MedicineDto();
        BeanUtils.copyProperties(medicine,medicineDto);


        LambdaQueryWrapper<MedicineStandard> medicineStandardLambdaQueryWrapper = new LambdaQueryWrapper<>();
        medicineStandardLambdaQueryWrapper.eq(MedicineStandard::getMedicineId,id);

        List<MedicineStandard> medicineStandards = medicineStandardService.list(medicineStandardLambdaQueryWrapper);


        medicineDto.setStandards(medicineStandards);

        return medicineDto;
    }


    @Transactional
    @Override
    public void updateWithStandard(MedicineDto medicineDto) {
        //更新药品表
        this.updateById(medicineDto);

        //更新使用标准
        /**
         * 1.清理先前的使用标准
         * 2.插入新的使用标准信息
         */
        //清理使用标准

        LambdaQueryWrapper<MedicineStandard> medicineStandardLambdaQueryWrapper = new LambdaQueryWrapper<>();
        medicineStandardLambdaQueryWrapper.eq(MedicineStandard::getMedicineId,medicineDto.getId());
        medicineStandardService.remove(medicineStandardLambdaQueryWrapper);
        //接着将medicineStandard插入对应的值
        List<MedicineStandard> flavors = medicineDto.getStandards();
        //前端只传回来使用标准名和对应的值 并没有对应的药品的id
        List<MedicineStandard> list = flavors.stream().map(item -> {
            item.setMedicineId(medicineDto.getId());
            return item;
        }).collect(Collectors.toList());


        medicineStandardService.saveBatch(list);



    }


    @Transactional
    @Override
    public void deleteByIds(List<Long> ids) {
//        //删除药品信息
//        this.removeByIds(ids);
//        //删除使用标准信息
//        medicineStandardService.removeByIds(ids);

        for (int i = 0; i < ids.size(); i++) {
            LambdaQueryWrapper<MedicineStandard> medicineStandardLambdaQueryWrapper = new LambdaQueryWrapper<>();
            medicineStandardLambdaQueryWrapper.eq(MedicineStandard::getMedicineId,ids.get(i));
            LambdaQueryWrapper<Medicine> medicineLambdaQueryWrapper = new LambdaQueryWrapper<>();
            medicineLambdaQueryWrapper.eq(Medicine::getId,ids.get(i));
            this.remove(medicineLambdaQueryWrapper);
            medicineStandardService.remove(medicineStandardLambdaQueryWrapper);
        }
    }

    @Override
    public R<Page> getPage(int page, int pageSize, String name) {
//构造分页构造器
        Page<Medicine> medicinePage = new Page<>(page, pageSize);
        Page<MedicineDto> medicineDtoPage = new Page<>();

        //条件构造器
        LambdaQueryWrapper<Medicine> medicineLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //过滤条件name的模糊查询
        if (name != null) medicineLambdaQueryWrapper.like(Medicine::getName, name);
        //添加排序条件
        medicineLambdaQueryWrapper.orderByDesc(Medicine::getUpdateTime);
        //执行分页查询
        medicineService.page(medicinePage, medicineLambdaQueryWrapper);


        /**
         * 当分页查询执行后medicinePage已经有数据了
         * 然后将medicinePage拷贝给medicineDtoPage
         * 忽略records
         */
        BeanUtils.copyProperties(medicinePage, medicineDtoPage, "records");
        //medicinePage展示的内容（缺少药品分类）
        List<Medicine> medicinerecords = medicinePage.getRecords();
        List<MedicineDto> list=medicinerecords.stream().map((item) -> {
            //将普通属性拷贝给Dto对象
            MedicineDto medicineDto = new MedicineDto();
            BeanUtils.copyProperties(item,medicineDto);


            //拿到records里面的分类id
            Long categoryId = item.getCategoryId();
            //通过id拿到分类对象
            Category categoryById = categoryService.getById(categoryId);
            //通过分类对象拿到分类的名称
            String categoryName = categoryById.getName();
            //最后将分类名传给Dto对象
            medicineDto.setCategoryName(categoryName);


            return medicineDto;
        }).collect(Collectors.toList());
        medicineDtoPage.setRecords(list);
        return R.success(medicineDtoPage);

    }
}
